package com.lhl.api.conver;

import cn.hutool.core.convert.Convert;
import com.google.common.collect.Maps;
import com.lhl.fw.core.base.BaseDbEnum;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.converter.ConverterFactory;

import java.util.Map;

/**
 * @className: com.lhl.fw.core.data.converter.EnumConvertFactory
 * @description: 枚举工厂转换类,把前端传的值转换成对应的枚举
 * @author: king
 * @date: 2020-11-17
 **/
@Api(tags = "EnumConvertFactory", produces = "枚举工厂转换类")
@Slf4j
public class EnumConvertFactory implements ConverterFactory<String, BaseDbEnum> {
    private static final Map<Class, Converter> CONVERTERS = Maps.newHashMap();
    /**
     * @param: aClass
     * @description: 获取一个从 String 转化为 T 的转换器，T 是一个泛型，有多个实现
     * @return: String和一个枚举的转换类
     * @author: king
     * @date: 2020-11-17
     */
    @Override
    public <T extends BaseDbEnum> Converter<String, T> getConverter(Class<T> targetType) {
        log.debug("{}开始转换",targetType.getName());
        Converter<String, T> converter = CONVERTERS.get(targetType);
        if (converter == null) {
            converter = new StringToIEum<>(targetType);
            CONVERTERS.put(targetType, converter);
        }
        return converter;
    }
    @SuppressWarnings("all")
    private static class StringToIEum<T extends BaseDbEnum> implements Converter<String, T> {

        private Class<T> targerType;
        public StringToIEum(Class<T> targerType) {
            this.targerType = targerType;
        }

        @Override
        public T convert(String source) {
            log.debug("{}开始转换",source);
            if (StringUtils.isEmpty(source)) {
                return null;
            }
            return (T) EnumConvertFactory.getIEnum(this.targerType, source);
        }
    }

    public static <T extends BaseDbEnum> Object getIEnum(Class<T> targerType, String source) {
        for (T enumObj : targerType.getEnumConstants()) {
            log.debug("enumObj.getDatabaseValue()=={}", Convert.toStr(enumObj.getDbValue()));
            if (source.equals(String.valueOf(enumObj.getDbValue()))) {
                return enumObj;
            }
        }
        return null;
    }
}
